package com.xbongbong.paas.enums;

import com.xbongbong.pro.statistic.constant.RelatedProductConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductionInstockEnum;
import com.xbongbong.saas.enums.business.ProductionMaterielOutstockEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInstockEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.ReceiptOrderEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.RefundInstockEnum;
import com.xbongbong.saas.enums.business.ReturnedMaterielInstockEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseOutstockEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.product.AssembleInProductEnum;
import com.xbongbong.saas.enums.product.AssembleProductEnum;
import com.xbongbong.saas.enums.product.BomFinishProductEnum;
import com.xbongbong.saas.enums.product.BomMaterielProductEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.InventoryProductEnum;
import com.xbongbong.saas.enums.product.OpportunityProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionInstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderFinishProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderMaterielProductEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.enums.product.QuotationProductEnum;
import com.xbongbong.saas.enums.product.RefundInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.SupplierProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author: 汪腾伟
 * @date: Created in 2021/8/11 15:53
 * @description： BI关联产品统计功能对原先逻辑进行改造，原先使用的BIProductEnum枚举
 */
@Getter
public enum BIProductReformEnum {
    /**
     * 1、主业务表单只有一个关联产品，且子产品数据单独存放。如机会、报价单等；
     * 2、主业务表单只有一个关联产品，但是子产品数据和其他业务的子产品在同一张表存放。如合同产品与退货退款产品都在tb_saas_contract_product表内；
     * 3、主业务表单有1个以上的关联产品字段，且businessType相同，子产品数据在同一张表存放，通过type区分。如BOM清单产品、生产单产品等；
     * 4、主业务表单有1个以上的关联产品字段，且businessType不相同，子产品数据在同一张表存放，通过type区分。如装配出入库单的出库产品、入库产品；
     */

    /**
     * tb_saas_contract_product.type 201合同202退货
     * 合同产品、退货退款产品
     *
     * linkMainBusinessType这个值定义的原因。因为之前产品-合同那边是定义了跟合同那边关联的字段是num_21,但是其他业务未有这种定义，所以其他业务都定义成这个attr。
     *                     这个值是人为定义，并没有实际含义。
     */
    //合同产品
    CONTRACT_PRODUCT(XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.CONTRACT_PRODUCT.getCode(), XbbRefTypeEnum.CONTRACT.getCode(), ContractEnum.PRODUCT.getAttr(), "contractId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ContractProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //退货退款产品
    REFUND_PRODUCT(XbbRefTypeEnum.REFUND.getCode(), XbbRefTypeEnum.CONTRACT_PRODUCT.getCode(), XbbRefTypeEnum.REFUND.getCode(), RefundEnum.PRODUCTS.getAttr(), "contractId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, RefundProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_opportunity_product
     * 销售机会产品
     */
    SALES_OPPORTUNITY_PRODUCT(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY_PRODUCT.getCode(), null, SalesOpportunityEnum.PRODUCTS.getAttr(), "opportunityId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, OpportunityProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_quotation_product
     * 报价单产品
     */
    QUOTATION_PRODUCT(XbbRefTypeEnum.QUOTATION.getCode(), XbbRefTypeEnum.QUOTATION_PRODUCT.getCode(), null, QuotationEnum.PRODUCT.getAttr(), "quotationId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, QuotationProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_supplier_product
     * 供应商产品
     */
    SUPPLIER_PRODUCT(XbbRefTypeEnum.SUPPLIER.getCode(), XbbRefTypeEnum.SUPPLIER_PRODUCT.getCode(), null, SupplierEnum.PRODUCT_LIST.getAttr(), "supplierId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, SupplierProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_purchase_product
     * 采购合同产品
     */
    PURCHASE_PRODUCT(XbbRefTypeEnum.PURCHASE.getCode(), XbbRefTypeEnum.PURCHASE_PRODUCT.getCode(), null, PurchaseEnum.PRODUCT.getAttr(), "purchaseSheetId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, PurchaseProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_returned_purchase_product
     * 采购退货单产品
     */
    RETURNED_PURCHASE_PRODUCT(XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), XbbRefTypeEnum.RETURNEDPURCHASE_PRODUCT.getCode(), null, ReturnedPurchaseEnum.PRODUCTS.getAttr(), "returnPurchaseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, PurchaseProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_bom_product.type 1成品 2物料
     * BOM清单产品-成品产品、物料产品
     */
    //BOM清单产品-成品产品
    BOM_BILL_PRODUCT(XbbRefTypeEnum.BOM_BILL.getCode(), XbbRefTypeEnum.BOM_BILL_PRODUCT.getCode(), 1, BomBillEnum.PRODUCT.getAttr(), "bomId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, BomFinishProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //BOM清单产品-物料产品
    BOM_BILL_MATERIEL(XbbRefTypeEnum.BOM_BILL.getCode(), XbbRefTypeEnum.BOM_BILL_PRODUCT.getCode(), 2, BomBillEnum.MATERIEL.getAttr(), "bomId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, BomMaterielProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_production_order_product.type 1代表成品 2代表物料
     * 生产单-成品产品、物料产品
     */
    //生产单-成品产品
    PRODUCTION_ORDER_PRODUCT(XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.PRODUCTION_ORDER_PRODUCT.getCode(), 1, ProductionOrderEnum.PRODUCT.getAttr(), "productionOrderId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ProductionOrderFinishProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //生产单-物料产品
    PRODUCTION_ORDER_MATERIEL(XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.PRODUCTION_ORDER_PRODUCT.getCode(), 2, ProductionOrderEnum.MATERIEL.getAttr(), "productionOrderId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ProductionOrderMaterielProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_assemble_product.type 1装配出库产品 2装配入库产品
     * 装配出入库单-出库产品、入库产品
     */
    //装配出入库单-出库产品
    ASSEMBLE_PRODUCT_OUT(XbbRefTypeEnum.ASSEMBLE.getCode(), XbbRefTypeEnum.ASSEMBLE_PRODUCT.getCode(), 1, AssembleEnum.OUT_PRODUCTS.getAttr(), "assembleId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, AssembleProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //装配出入库单-入库产品
    ASSEMBLE_PRODUCT_IN(XbbRefTypeEnum.ASSEMBLE.getCode(), XbbRefTypeEnum.ASSEMBLE_INPRODUCTS.getCode(), 2, AssembleEnum.IN_PRODUCTS.getAttr(), "assembleId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, AssembleInProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_inventory_product
     * 盘点单-盘点产品
     */
    INVENTORY_PRODUCT(XbbRefTypeEnum.INVENTORY.getCode(), XbbRefTypeEnum.INVENTORY_PRODUCT.getCode(), null, InventoryEnum.PRODUCT.getAttr(), "inventoryId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, InventoryProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_transfer_product
     * 调拨单-调拨产品
     */
    TRANSFER_PRODUCT(XbbRefTypeEnum.TRANSFER.getCode(), XbbRefTypeEnum.TRANSFER_PRODUCT.getCode(), null, TransferEnum.PRODUCTS.getAttr(), "transferId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, TransferProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_instock_product.type 1:采购入库,2:销售退货入库,3:盘盈入库,4:调拨入库,5:其他入库,6:装配入库,7:生产入库,8:生产退料
     * 入库产品【其中3、4、5、6都算其他入库产品，即查询同步其他入库产品时，需同时查3、4、6几种类型】
     */
    //入库产品-采购入库单
    PURCHASE_INSTOCK_PRODUCT(XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), XbbRefTypeEnum.INSTOCK_PRODUCT.getCode(), 1, PurchaseInstockEnum.PRODUCT.getAttr(), "intoWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, PurchaseInstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //入库产品-销售退货入库单
    REFUND_INSTOCK_PRODUCT(XbbRefTypeEnum.REFUND_INSTOCK.getCode(), XbbRefTypeEnum.INSTOCK_PRODUCT.getCode(), 2, RefundInstockEnum.PRODUCT.getAttr(), "intoWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, RefundInstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //入库产品-其他入库单 - 盘盈入库、调拨入库、装配入库也归属该类
    OTHER_INSTOCK_PRODUCT(XbbRefTypeEnum.OTHER_INSTOCK.getCode(), XbbRefTypeEnum.INSTOCK_PRODUCT.getCode(), 5, InstockEnum.PRODUCT.getAttr(), "intoWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, InstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //入库产品-生产入库单
    PRODUCTION_INSTOCK_PRODUCT(XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(), XbbRefTypeEnum.INSTOCK_PRODUCT.getCode(), 7, ProductionInstockEnum.PRODUCT.getAttr(), "intoWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ProductionInstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //入库产品-生产退料单
    RETURNED_MATERIEL_INSTOCK_PRODUCT(XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), XbbRefTypeEnum.INSTOCK_PRODUCT.getCode(), 8, ReturnedMaterielInstockEnum.PRODUCT.getAttr(), "intoWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ReturnedMaterielInstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),

    /**
     * tb_saas_outstock_product.type 1:采购退货出库,2:销售出库,3:盘亏出库,4:调拨出库,5:其他出库,6:装配出库,7:工单出库,8:生产领料出库
     * 出库产品 【其中3、4、5、6都算其他出库产品，即查询同步其他出库产品时，需同时查3、4、6几种类型】
     */
    //出库产品-销售出库单
    CONTRACT_OUTSTOCK_PRODUCT(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK_PRODUCT.getCode(), 2, ContractOutstockEnum.PRODUCT.getAttr(), "outWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ContractOutstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //出库产品-采购退货出库单
    RETURNED_PURCHASE_OUTSTOCK_PRODUCT(XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK_PRODUCT.getCode(), 1, ReturnedPurchaseOutstockEnum.PRODUCT.getAttr(), "outWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ReturnedPurchaseOutstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //出库产品-其他出库单 - 盘亏出库、调拨出库、装配出库也归属该类
    OTHER_OUTSTOCK_PRODUCT(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK_PRODUCT.getCode(), 5, OutstockEnum.PRODUCT.getAttr(), "outWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, OutstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //出库产品-生产领料单
    PRODUCTION_MATERIEL_OUTSTOCK_PRODUCT(XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK_PRODUCT.getCode(), 8, ProductionMaterielOutstockEnum.PRODUCT.getAttr(), "outWarehouseId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ProductionMaterielOutstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    //回执单-关联产品
    RECEIPT_ORDER_PRODUCT(XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getCode(), XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getCode(), 8, ReceiptOrderEnum.PRODUCT.getAttr(), "receiptOrderId", RelatedProductConstant.COMMON_DB_PRODUCT_NO, RelatedProductConstant.COMMON_DB_PRODUCT_NAME, ProductionMaterielOutstockProductEnum.PRODUCT.getAttr(), RelatedProductConstant.LINK_MAINBUSINESS_ATTR, RelatedProductConstant.LINK_PRODUCT_ATTR),
    ;

    /**
     * 产品关联的主业务业务类型
     */
    private Integer businessType;

    /**
     * 产品子表单businessType
     */
    private Integer subProductBusinessType;

    /**
     * 增加一个字段用于区分产品，比如bom单中有成品产品和物料产品，得有标识去区分，
     * 值最好要用各自产品表中的type字段，比如tb_saas_bom_product中有type去区分成品和物料
     */
    private Integer type;

    /**
     * 主业务的产品attr
     * 如合同内的 关联产品字段
     * (主表中存的关联产品字段，不用作直接关联，模板中的占位字段)
     */
    private String mainLinkProductAttr;

    /**
     * 比如，产品-合同子表单数据库表中用于存主业务id的数据库字段-》对应java实体的字段
     * 数据库内的主业务字段，为了通过反射获取其值
     */
    private String dbFieldLinkMainBusiness;

    /**
     * 比如，产品-合同子表单数据库表中用于存产品编号的数据库字段-》对应java实体的字段；现状都用一个常量去维护，后面如果有哪个业务不一样的化，自己改动
     */
    private String dbFieldProductNo;

    /**
     * 比如，产品-合同子表单数据库表中用于存产品名称的数据库字段-》对应java实体的字段；现状都用一个常量去维护，后面如果有哪个业务不一样的化，自己改动
     */
    private String dbFieldProductName;

    /**
     * 产品子表单的产品名称attr，相当于产品子表单内的 关联产品id（与表单设计对应）
     * 1、从宽表data内读取产品id
     * 2、同时attr作为产品名称用于数仓（数仓内实际字段会重新计算）
     * (关联产品表中存的产品id)
     */
    private String subLinkProductAttr;

    /**
     * 产品子表单关联主业务的attr，RelatedProductConstant.LINK_MAINBUSINESS_ATTR
     * 相当于合同产品表data内的关联合同id（表单设计内无主业务id，因此模拟出一个attr）
     * 打到数仓内时使用 - 代表关联合同id attr （数仓内实际字段会重新计算）
     */
    private String virtualLinkMainBusinessAttr;

    /**
     * 虚拟的产品子表单关联产品的attr，RelatedProductConstant.LINK_PRODUCT_ATTR
     * 打到数仓内时使用 - 代表关联产品id attr （数仓内实际字段会重新计算）
     */
    private String virtualLinkProductAttr;


    BIProductReformEnum(Integer businessType, Integer subProductBusinessType, Integer type, String mainLinkProductAttr, String dbFieldLinkMainBusiness, String dbFieldProductNo, String dbFieldProductName, String subLinkProductAttr, String virtualLinkMainBusinessAttr, String virtualLinkProductAttr) {
        this.businessType = businessType;
        this.subProductBusinessType = subProductBusinessType;
        this.type = type;
        this.mainLinkProductAttr = mainLinkProductAttr;
        this.dbFieldLinkMainBusiness = dbFieldLinkMainBusiness;
        this.dbFieldProductNo = dbFieldProductNo;
        this.dbFieldProductName = dbFieldProductName;
        this.subLinkProductAttr = subLinkProductAttr;
        this.virtualLinkMainBusinessAttr = virtualLinkMainBusinessAttr;
        this.virtualLinkProductAttr = virtualLinkProductAttr;
    }

    /**
     * 获取所有产品子表单父类业务类型
     *
     * @return
     */
    public static Set<Integer> getAllBusinessTypes() {
        Set<Integer> businessTypeList = new HashSet<>();
        for (BIProductReformEnum productReformEnum : BIProductReformEnum.values()) {
            businessTypeList.add(productReformEnum.getBusinessType());
        }
        return businessTypeList;
    }

    /**
     *根据主业务类型去获取信息
     *
     * @param businessType 业务类型
     * @return
     */
    public static List<BIProductReformEnum> getBIProductReformEnumByBus(Integer businessType) {
        List<BIProductReformEnum> biProductReformEnumList = new ArrayList<>();
        for (BIProductReformEnum productReformEnum : BIProductReformEnum.values()) {
            if (Objects.equals(businessType, productReformEnum.getBusinessType())) {
                biProductReformEnumList.add(productReformEnum);
            }
        }
        return biProductReformEnumList;
    }

    /**
     * 获取所有的枚举
     *
     * @return
     */
    public static List<BIProductReformEnum> getAllBiProductReformEnums() {
        List<BIProductReformEnum> allBiProductReformEnums = new ArrayList<>();
        for (BIProductReformEnum biProductReformEnum : values()) {
            allBiProductReformEnums.add(biProductReformEnum);
        }
        return allBiProductReformEnums;
    }

    /**
     * 获取业务中有多个产品的枚举
     *
     * @return
     */
    public static List<BIProductReformEnum> getMultipleProductEnums() {
        return Arrays.asList(BOM_BILL_PRODUCT, BOM_BILL_MATERIEL, PRODUCTION_ORDER_PRODUCT, PRODUCTION_ORDER_MATERIEL, ASSEMBLE_PRODUCT_OUT, ASSEMBLE_PRODUCT_IN);
    }

    /**
     * 获取业务中有多个产品的业务code
     *
     * @return
     */
    public static Set<Integer> getMultipleProductCodeList() {
        Set<Integer> productSubBusSet = new HashSet<>();
        for (BIProductReformEnum biProductReformEnum : getMultipleProductEnums()) {
            productSubBusSet.add(biProductReformEnum.getSubProductBusinessType());
        }
        return productSubBusSet;
    }

    /**
     * 获取主业务有多个产品的主业务code
     *
     * @return
     */
    public static Set<Integer> getMainMultipleProductCodeList() {
        Set<Integer> productSubBusSet = new HashSet<>();
        for (BIProductReformEnum biProductReformEnum : getMultipleProductEnums()) {
            productSubBusSet.add(biProductReformEnum.getBusinessType());
        }
        return productSubBusSet;
    }

    /**
     * 获取产品子表单的业务类型集合
     *
     * @return
     */
    public static Set<Integer> getProductSubBusList() {
        Set<Integer> productSubBusSet = new HashSet<>();
        for (BIProductReformEnum biProductReformEnum : BIProductReformEnum.values()) {
            productSubBusSet.add(biProductReformEnum.getSubProductBusinessType());
        }
        return productSubBusSet;
    }

    /**
     * 根据产品子表单业务类型获取枚举
     *
     * @param linkProductBusinessType
     * @return
     */
    public static BIProductReformEnum getEnumByProductBusinessType(Integer linkProductBusinessType) {
        for (BIProductReformEnum biProductReformEnum : values()) {
            if (Objects.equals(linkProductBusinessType, biProductReformEnum.getSubProductBusinessType())) {
                return biProductReformEnum;
            }
        }
        return null;
    }

    /**
     * 多表关联那边的默认值需要这个判断
     *
     * @return
     */
    public static Set<Integer> getDefineDefaultRelBus() {
        Set<Integer> defineDefaultRelBusList = new HashSet<>();
        for (BIProductReformEnum biProductReformEnum : BIProductReformEnum.values()) {
            if (Objects.nonNull(biProductReformEnum.getType())) {
                defineDefaultRelBusList.add(biProductReformEnum.getSubProductBusinessType());
            }
        }
        return defineDefaultRelBusList;
    }

    /**
     *
     *
     * @param linkProductBusinessType 产品子表单的业务类型
     * @param type type
     * @return
     */
    public static BIProductReformEnum getBiProductReformByType(Integer linkProductBusinessType, Integer type) {
        for (BIProductReformEnum biProductReformEnum : BIProductReformEnum.values()) {
            if (Objects.equals(linkProductBusinessType, biProductReformEnum.getSubProductBusinessType()) && Objects.equals(type, biProductReformEnum.getType())) {
                return biProductReformEnum;
            }
        }
        return null;
    }

    /**
     * 获取产品在主业务中的attr
     *
     * @param linkProductBusinessType
     * @param type
     * @return
     */
    public static String getProductAttr(Integer linkProductBusinessType, Integer type) {
        BIProductReformEnum biProductReformEnum = getBiProductReformByType(linkProductBusinessType, type);
        if (Objects.isNull(biProductReformEnum)) {
            return null;
        }else {
            return biProductReformEnum.getMainLinkProductAttr();
        }
    }

    /**
     * 获得关联产品表内的主业务id字段
     * 比如，产品-合同子表单数据库表中用于存主业务id的数据库字段-》对应java实体的字段数据库内的主业务字段
     * @return java.util.List<java.lang.String>
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static Set<String> getAllDbFieldLinkMainBusiness(){
        Set<String> set = new HashSet<>();
        for (BIProductReformEnum cache : values()) {
            set.add(cache.dbFieldLinkMainBusiness);
        }
        return set;
    }
}
